﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace Zocono.WCS.WMSApiDomain.WebApi
{
    public class SimpleApiClient
    {
        public static HttpClient CreateHttpClient()
        {
            var handler = GetInsecureHandler();
            HttpClient httpClient = new HttpClient(handler);
            httpClient.Timeout = TimeSpan.FromSeconds(60);
            //{
            //    MaxResponseContentBufferSize = 256000
            //};
            httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
            return httpClient;
        }

        public static async Task<T> PostAsync<T>(string url, object data) where T : class, new()
        {
            try
            {
                var client = CreateHttpClient();
                string content = JsonConvert.SerializeObject(data);
                var buffer = Encoding.UTF8.GetBytes(content);
                var byteContent = new ByteArrayContent(buffer);
                byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                var response = await client.PostAsync(url, byteContent).ConfigureAwait(false);
                string result = await response.Content.ReadAsStringAsync();
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    throw new Exception($"GetAsync End, url:{url}, HttpStatusCode:{response.StatusCode}, result:{result}");
                }
                if (typeof(T) == typeof(string))
                {
                    return (T)(object)result;
                }

                return JsonConvert.DeserializeObject<T>(result);
            }
            catch (WebException ex)
            {
                if (ex.Response != null)
                {
                    string responseContent = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
                    throw new System.Exception($"response :{responseContent}", ex);
                }
                throw;
            }
        }

        public static async Task<T> GetAsync<T>(string url, object data)
        {
            try
            {
                string requestUrl = data == null ? url : $"{url}?{GetQueryString(data)}";
                var client = CreateHttpClient();
                var response = await client.GetAsync(requestUrl).ConfigureAwait(false);
                string content = await response.Content.ReadAsStringAsync();
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    throw new Exception($"GetAsync End, url:{url}, HttpStatusCode:{response.StatusCode}, result:{content}");
                }
                if (typeof(T) == typeof(string))
                {
                    return (T)(object)content;
                }
                var result = JsonConvert.DeserializeObject<T>(content);
                return result;
            }
            catch (WebException ex)
            {
                if (ex.Response != null)
                {
                    string responseContent = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
                    throw new Exception($"Response :{responseContent}", ex);
                }
                throw;
            }
        }

        public static async Task<T> GetAsync<T>(string url)
        {
            try
            {
                string requestUrl = url;
                var client = CreateHttpClient();
                var response = await client.GetAsync(requestUrl).ConfigureAwait(false);
                string content = await response.Content.ReadAsStringAsync();
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    throw new Exception($"GetAsync End, url:{url}, HttpStatusCode:{response.StatusCode}, result:{content}");
                }
                if (typeof(T) == typeof(string))
                {
                    return (T)(object)content;
                }
                var result = JsonConvert.DeserializeObject<T>(content);
                return result;
            }
            catch (WebException ex)
            {
                if (ex.Response != null)
                {
                    string responseContent = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
                    throw new Exception($"Response :{responseContent}", ex);
                }
                throw;
            }
        }

        private static string GetQueryString(object obj)
        {
            var properties = from p in obj.GetType().GetProperties()
                             where p.GetValue(obj, null) != null
                             select p.Name + "=" + HttpUtility.UrlEncode(p.GetValue(obj, null).ToString());

            return string.Join("&", properties.ToArray());
        }

        /// <summary>
        /// 如果是本地服务，不使用https
        /// </summary>
        /// <returns></returns>
        private static HttpClientHandler GetInsecureHandler()
        {
            var handler = new HttpClientHandler();
            handler.UseDefaultCredentials = true;
            //handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
            //{
            //    if (cert.Issuer.Equals("CN=localhost"))
            //        return true;
            //    return errors == System.Net.Security.SslPolicyErrors.None;
            //};
            return handler;
        }
    }
}
